use std::env;

use anyhow::Result;
use sea_orm::{Database, DbConn};

use migration::{Migrator, MigratorTrait};

use crate::apis::AriaRpc;
use crate::schedule::{start_queue, Notifier, Submitter};

#[derive(Debug, Clone)]
pub struct AppState {
    pub db: DbConn,
    pub aria_rpc: AriaRpc,
    pub submitter: Submitter,
    pub notifier: Notifier,
}

impl AppState {
    pub async fn init() -> Result<Self> {
        let db = init_db().await?;
        let aria_rpc = AriaRpc::new();
        let (submitter, notifier) = start_queue(db.clone(), aria_rpc.clone()).await;

        Ok(Self {
            db,
            aria_rpc,
            submitter,
            notifier,
        })
    }
}

async fn init_db() -> Result<DbConn> {
    let url = env::var("DATABASE_URL")?;
    let db = Database::connect(url).await?;
    Migrator::up(&db, None).await?;
    Ok(db)
}
